use tokio::{net::TcpStream, time::timeout, io::AsyncWriteExt};
use crate::{error::{AppErr, ErrorHandler}, robot::ctrl_proto::{build_req, read_resp_with_timeout}};
use super::{CTRL_ADDR, CONNECT_DURATION, ctrl_proto::CtrlProto};

pub struct CtrlConn {

    stream: TcpStream,
    cnt: u16,
}

impl CtrlConn {

    pub async fn connect() -> Result<Self, AppErr> {
        let stream = TcpStream::connect(CTRL_ADDR);
        let stream = timeout(CONNECT_DURATION, stream)
            .await
            .map_app("连接CTRL超时")??;
        
        let conn = CtrlConn {
            stream,
            cnt: 0,
        };
        Ok(conn)
    }

    pub async fn request(&mut self, cmd_code: u32, name: &str, args: &[String]) -> Result<CtrlProto, AppErr> {

        let cnt = self.cnt;
        self.cnt += 1;

        let req_str = build_req(cnt, cmd_code, name, args);
        self.stream.write_all(req_str.as_bytes()).await?;

        let resp = read_resp_with_timeout(&mut self.stream).await?;

        Ok(resp)
    }

}


